package com.station.utils;

import cn.hutool.crypto.digest.DigestUtil;
import lombok.extern.slf4j.Slf4j;

import java.net.URLEncoder;
import java.util.*;

/**
 * Function: 签名用的工具箱
 * @author
 */
@Slf4j
public class SignUtil {

    /**
     * <功能详细描述>获取签名
     * @param bean
     * @param key
     * @return String
     */
    public static String sign(Object bean, String key){
        String signStr = paramsToString(bean) + "&key=" + key;
        String sign = DigestUtil.md5Hex(signStr);
        log.info("SignStr : {}", signStr);
        log.info("Sign : {}", sign);
        return sign;
    }

    /**
     * <功能详细描述>获取签名
     * @param paramMap
     * @param key
     * @return String
     */
    public static String sign(Map<String, String> paramMap, String key){
        String signStr = paramsToString(paramMap) + "&key=" + key;
        String sign = DigestUtil.md5Hex(signStr);
        log.info("SignStr : {}", signStr);
        log.info("Sign : {}", sign);
        return sign;
    }

    /**
     * <功能详细描述>将Object Bean转成String
     * @param bean
     * @return String
     */
    public static String paramsToString(Object bean){
        Map<String, String> paramMap = new HashMap<String, String>();
        String[] filedNames = ObjectElementUtil.getFiledName(bean);
        if(null != filedNames) {
            for (int i = 0; i < filedNames.length; i++) {
                Object _obj = ObjectElementUtil.getFieldValueByName(filedNames[i], bean);
                paramMap.put(filedNames[i], null == _obj ? null : String.valueOf(_obj));
            }
        }
        return paramsToString(paramMap);
    }

    /**
     * <功能详细描述>将map转成String
     * @param paramMap
     * @return String
     */
    public static String paramsToString(Map<String, String> paramMap){
        return paramsToString(paramMap, false);
    }

    public static String paramsToString(Map<String, String> paramMap, boolean encoding){
        return paramsToString(new StringBuilder(), paramMap, encoding);
    }

    public static String paramsToString(StringBuilder sb, Map<String, String> paramMap, boolean encoding){
        buildPayParams(sb, paramFilter(paramMap), encoding);        // 必须过滤参数
        return sb.toString();
    }

    /**
     * 过滤参数(空参、参数[sign])
     * @author
     * @param paramMap
     * @return Map
     */
    public static Map<String, String> paramFilter(Map<String, String> paramMap) {
        Map<String, String> result = new HashMap<String, String>(paramMap.size());
        if (paramMap == null || paramMap.size() <= 0) {
            return result;
        }
        for (String key : paramMap.keySet()) {
            String value = paramMap.get(key);
            if (value == null || value.equals("") || key.equalsIgnoreCase("sign")) {        // 签名 or 验签 移除sign
                continue;
            }
            result.put(key, value);
        }
        return result;
    }

    /**
     * @param sb
     * @param paramMap
     * @param encoding
     * @return
     */
    public static void buildPayParams(StringBuilder sb, Map<String, String> paramMap, boolean encoding){
        List<String> keys = new ArrayList<String>(paramMap.keySet());
        Collections.sort(keys);
        for(String key : keys){
            sb.append(key).append("=");
            if(encoding){
                sb.append(urlEncode(paramMap.get(key)));
            }else{
                sb.append(paramMap.get(key));
            }
            sb.append("&");
        }
        sb.setLength(sb.length() - 1);
    }

    /**
     * @param str
     * @return
     */
    public static String urlEncode(String str){
        try {
            return URLEncoder.encode(str, "UTF-8");
        } catch (Throwable e) {
            return str;
        }
    }

}
